<?php

/**
 * Representa a instancia de um usuario no sistema
 */
class Usuario implements IObject {

    /**
     * Objeto de manipulação de Banco
     * @var tMysqli     MyDb Object
     */
    public $tMysqli;
    /**
     * ID do usuario no sistema
     * @var $IDUsuario   integer
     */
    private $IDUsuario;
    /**
     * Array com os dados do usuario (TABELA:dra__Usuario)
     * @var $ArDadosUsuario  Array de Strings
     */
    private $ArDadosUsuario;
    /**
     * Array com os dados administrativos do usuario (TABELA:dra__Administracao)
     * @var $ArDadosAdministracao  Array de Strings
     */
    private $ArDadosAdministracao;
    /**
     * Array com instancias de Dependentes do usuario (TABELA:dra__Dependentes)
     * @var $ArDependentes  Array de Dependente Object
     */
    private $ArDependentes;
    /**
     * Array com instancias de Ferramentas Habilitadas pelo usuario (TABELA:TABELA:dra__Ferramentas,dra__FerramentasHabilitadas)
     * @var $ArFerramentas  Array de Ferramenta Object
     */
    private $ArFerramentas;
    /**
     * Array com todas as preferencias do usuario (Tabela:dra__Preferencias)
     * @var ArPreferencias  Array String
     */
    private $ArPreferences;
    /**
     * Funcao do Usuario no sistema contem Perfil (TABELA:dra__Funcao)
     * @var $tPerfil  Perfil Object
     */
    private $tPerfil;
    /**
     * Departamento atual do usuario (TABELA:dra__Departamento)
     * @var $tDepartamento   Departamento Object
     */
    private $tDepartamento;
    /**
     * Array com todos os pagamentos do Usuario (TABELA:dra__Pagamento)
     * @var $ArPagamentos   Pagamento Object
     */
    private $ArPagamentos;

    private $ArChamadosPreferidos;
    /**
     * Variavel para disponibilizar rollback caso alguma query de errado
     * @var backup  mixed
     */
    private $backup;
    /**
     * Relatorio individual do Cliente
     * @var report  array
     */
    private $Report;

    public function __construct($IDUsuario, &$tMysqli, $IsSimple = false) {
        $this->IDUsuario = $IDUsuario;
        $this->tMysqli = $tMysqli;
        if( !$IsSimple ) {
            $this->load();
        } else {
            $this->loadSimple();
        }
    }

    /**
     * @method  loadUser    @version 2
     *
     * Carrega todos os dados do usuario
     *
     * @since   2011-12-24
     * @author  Richard Brandao <richardsbrandao@gmail.com>
     * @return  void
     */
    private function load() {
        $this->loadUserData();
        $this->loadAdministrationData();
        $this->loadAllDependents();
        $this->loadAllPreferences();
        $this->loadProfile();
        $this->loadDepartament();
        $this->loadAllPayments();
        $this->loadFavedCalled();
        $this->loadAllTools();
    }

    private function loadSimple() {
        $this->loadUserData();
        $this->loadAdministrationData();
        $this->loadProfile();
    }

    /**
     * @method  loadUserData    @version 2
     *
     * Carrega todos os dados pessoais do usuario (Tabela:dra__Usuario)
     *
     * @since   2011-12-24
     * @author  Richard Brandao <richardsbrandao@gmail.com>
     * @return  void
     */
    private function loadUserData() {
        $StSql = TQuery::getSqlUserLoad($this->IDUsuario);
        $this->tMysqli->exec($StSql);
        $ArUserData = $this->tMysqli->fetchAll();
        $this->ArDadosUsuario = $ArUserData[0];
    }

    /**
     * @method  loadAdminsitrationData    @version 2
     *
     * Carrega todos os dados administrativos do usuario (Tabela:dra__Administracao)
     *
     * @since   2011-12-24
     * @author  Richard Brandao <richardsbrandao@gmail.com>
     * @return  void
     */
    private function loadAdministrationData() {
        $StSql = TQuery::getSqlAdmLoad($this->IDUsuario);
        $this->tMysqli->exec($StSql);
        $ArAdmData = $this->tMysqli->fetchAll();
        $this->ArDadosAdministracao = $ArAdmData[0];
    }

    /**
     * @method  loadAllDependents
     *
     * Carrega todos os dados dependentes do usuario
     *
     * @since   2011-12-24
     * @author  Richard Brandao <richardsbrandao@gmail.com>
     * @return  void
     */
    private function loadAllDependents() {
        $StSql = TQuery::getSqlDependentLoad($this->IDUsuario);
        $tQuery = $this->tMysqli->exec($StSql);
        while ($ArDependente = mysqli_fetch_assoc($tQuery)) {
            $this->ArDependentes[$ArDependente['IDDependente']] = new Dependente($ArDependente['IDDependente'], $ArDependente['IDAdministracao'], $ArDependente['StNome'], $ArDependente['DtNascimento'], $ArDependente['StGrauParentesco'], $this->tMysqli);
  }
    }

    /**
     * @method  loadAllTools    @version 2
     *
     * Carrega todos as ferramentas habilitadas do usuario
     *
     * @since   2011-12-24
     * @author  Richard Brandao <richardsbrandao@gmail.com>
     * @return  void
     */
    private function loadAllTools() {
        $StSql = TQuery::getSqlFerramentasHabilitadasLoad($this->IDUsuario);
        $tQuery = $this->tMysqli->exec($StSql);
        while( $ArFerramentasData = mysqli_fetch_assoc($tQuery) ) {
            $Ferramenta = new Ferramenta($ArFerramentasData, $this->tMysqli);
            $Ferramenta->setUsuario($this);
            $Ferramenta->loadRank( MAX_VALUES_IN_RANK_TOOL );
            $this->ArFerramentas[] = $Ferramenta;
        }
    }

    /**
     * @method  loadAllPreferences  @version 2
     *
     * Carrega todas as preferencias do usuario
     *
     * @since   2011-12-25
     * @author  Richard Brandao <richardsbrandao@gmail.com>
     * @return  void
     */
    public function loadAllPreferences() {
        $StSql = TQuery::getSqlPreferencesLoad($this->IDUsuario);
        $this->tMysqli->exec($StSql);
        $ArPreferences = $this->tMysqli->fetchAll();
        $this->ArPreferences = $ArPreferences[0];
    }

    /**
     * @method  loadProfiles
     *
     * Carrega o Perfil do usuario na empresa referente (Tabela:dra__Perfil),
     * tambem carrega a Funcao e os Privilegios do Perfil
     *
     * @since   2011-12-24
     * @author  Richard Brandao <richardsbrandao@gmail.com>
     * @return  void
     */
    private function loadProfile() {
        $StSql = TQuery::getSqlPerfilLoad($this->IDUsuario);
        $this->tMysqli->exec($StSql);
        $this->tPerfil = new Perfil($this->tMysqli->result(0, 'IDPerfil'), $this->tMysqli->result(0, 'IDFuncao'), $this->tMysqli->result(0, 'StPerfil'), $this->tMysqli);
        $this->tPerfil->loadPosition();
        $this->tPerfil->loadPermissions();
    }

    /**
     * @method  loadDepartament    @version 2
     *
     * Carrega o departamento em que o usuario pertence na empresa (tabela:dra__Departamento),
     * tambem carrega os setores que o usuario pertence.
     *
     * @since   2011-12-24
     * @author  Richard Brandao <richardsbrandao@gmail.com>
     * @return  void
     */
    private function loadDepartament() {
        $StSql = TQuery::getSqlDepartamentUserLoad($this->IDUsuario);
        $this->tMysqli->exec($StSql);
        $this->tDepartamento = new Departamento($this->tMysqli->result(0, 'IDDepartamento'), $this->tMysqli->result(0, 'StDepartamento'), $this->IDUsuario, $this->tMysqli);
        $this->tDepartamento->loadSectors();
    }

    private function loadAllPayments() {
        $StSql = TQuery::getSqlFindAllPaymentsByUser($this->IDUsuario);
        $tQuery = $this->tMysqli->exec($StSql);
        while($ArPaymentData = mysqli_fetch_assoc($tQuery)) {
            $this->ArPagamentos[] = new Pagamento($ArPaymentData, $this->tMysqli);
        }
    }

    public function loadFavedCalled() {
        $StSql = TQuery::getSqlFindFavedCalledByUser($this->IDUsuario);
        $tQuery = $this->tMysqli->exec($StSql);
        while($ArFavedCalledData = mysqli_fetch_assoc($tQuery)) {
            $this->ArChamadosPreferidos[] = Chamado::calledFactory($ArFavedCalledData, $this->tMysqli);
        }
    }

    public function equals(IObject $Usuario) {
        return ($this->IDUsuario == $Usuario->getIDUsuario());
    }

    /**
     * @method  updateUserData
     *
     * Atualiza os dados do usuario logado em sessao
     *
     * @param   Array    $ArUserData    Dados Administrativos e Pessoais que serao atualizados no usuario
     *
     * @return  boolean
     * @since   Outubro de 2010
     * @author  Richard Brandao <richardsbrandao@gmail.com>
     */
    public function updateUserData($ArUserData) {
        $this->backup = $this->getArDadosUsuario();
        foreach ($ArUserData as $StProp => $MxValue) {
            $this->setDadosUsuario($MxValue, $StProp);
        }
        $StSql = TQuery::getSqlUpdateUser($this->IDUsuario, $this->getArDadosUsuario());
        $this->tMysqli->exec($StSql);
        if (!$this->tMysqli->lastQueryReturn()) {
            $this->ArDadosUsuario = $this->backup;
        }
        unset($this->backup);
        return $this->tMysqli->lastQueryReturn();
    }
    /**
     * @method  updateDependents
     *
     * Atualiza, Insere e Deleta os dependentes do usuario
     *
     * @param   Array               $ArDependents       Array com os dados dos dependentes que foram Atualizados, Inseridos ou Deletados
     * @param   DependenteService   $dependenteService  Servico de dependente do sistema
     *
     * @return  void
     * @since   Janeiro de 2011
     * @author  Richard Brandao <richardsbrandao@gmail.com>
     */
    public function updateDependents($ArDependents, $dependentService) {
        if( !empty($ArDependents['Update']) ) {
            foreach ($ArDependents['Update'] as $tDependent) {
                $dependentService->update($tDependent, $this->tMysqli);
            }
        }
        if( !empty($ArDependents['Insert']) ) {
            foreach ($ArDependents['Insert'] as $ArDependent) {
                $tDependent = new Dependente(false, $this->getArDadosAdministracao('IDAdministracao'), $ArDependent['StNomeDependente'], $ArDependent['DtNascimentoDependente'], $ArDependent['StGrauParentesco'], $this->tMysqli);
                $dependentService->save($tDependent, $this->tMysqli);
            }
        }
        if( !empty($ArDependents['Delete']) ) {
            foreach ($ArDependents['Delete'] as $IDDependente) {
                $dependentService->delete($IDDependente, $this->tMysqli);
            }
        }
        $this->tMysqli->endTransaction();
        unset($this->ArDependentes);
        $this->loadAllDependents();
    }
    /**
     * @method  updateTools
     *
     * Insere e Deleta as ferramentas que foram habilitadas ou desabilitadas no post
     *
     * @param   Array               $ArTools            Array com as ferramentas que serao Inseridas ou deletadas pelo usuario
     *          FerramentaService   $ferramentaService  Array com os dados das ferramentas que serao atualizadas
     *
     * @return  boolean
     * @since   Novembro de 2010
     * @author  Richard Brandao <richardsbrandao@gmail.com>
     */
    public function updateTools($ArTools, $ferramentasService) {
        $ArStatusTools = $ferramentasService->getIdToolsUpdatedList($ArTools, $this->getFerramentas());

        foreach ($ArStatusTools['Insert'] as $IDFerramenta) {
            $ferramentasService->enableTool($IDFerramenta, $this->IDUsuario, $this->tMysqli);
        }

        foreach ($ArStatusTools['Delete'] as $IDFerramenta) {
            $ferramentasService->disableTool($IDFerramenta, $this->IDUsuario, $this->tMysqli);
        }

        unset($this->ArFerramentas);
        $this->loadAllTools();
    }
    /**
     * @method  updatePreferences
     *
     * Atualiza as preferencias do usuario logado
     *
     * @param   Array    $ArPreferences     Array com as preferencias que serao atualizadas
     *
     * @return  boolean
     * @since   Novembro de 2010
     * @author  Richard Brandao <richardsbrandao@gmail.com>
     */
    public function updatePreferences($ArPreferences) {
        $this->backup = $this->getPreferencias();
        foreach ($ArPreferences as $StPreference => $MxValue) {
            $this->setPreferencia($MxValue, $StPreference);
        }
        $StSql = TQuery::getSqlUpdatePreferences($this->IDUsuario, $this->getPreferencias());
        $this->tMysqli->exec($StSql);
        if (!$this->tMysqli->lastQueryReturn()) {
            $this->ArPreferences = $this->backup;
        }
        unset($this->backup);
        return $this->tMysqli->lastQueryReturn();
    }

    public function isContractor() {
        return $this->ArDadosAdministracao['EnStatus'] == 'CONTRATADO';
    }

    public function getShowedData() {
        return array(
            'data' => substr(dateBDtoBR($this->ArDadosUsuario['DtNascimento']), 0, 5),
            'title' => $this->ArDadosUsuario['StNome']
        );
    }

    public function hasThisPeriodPayment($StPeriod) {
        if( empty($this->ArPagamentos) ) { return false; }
        foreach($this->ArPagamentos as $Pagamento) {
            if($Pagamento->getStPeriodo() == $StPeriod) {
                return true;
            }
        }
        return false;
    }

    public function hasPayment($IDPagamento) {
        foreach($this->ArPagamentos as $Pagamento) {
            if( $IDPagamento == $Pagamento->getIDPagamento() ) {
                return true;
            }
        }
        return false;
    }

    public function hasPayments() {
        return !empty($this->ArPagamentos);
    }

    public function can($ActionName) {
        multipleEntities($ActionName);
        foreach( $this->tPerfil->getActions() as $Action ) {
            if( $Action->getStAcao() == $ActionName ) {
                return true;
            }
        }
        return false;
    }

    public function canCloseThis( Chamado $Chamado ) {
        if( $Chamado->isClosed() || $Chamado->isExternalCalled() || $Chamado->isPhoneCalled() ) {
            return false;
        }
        if( $this->can('Fechar Chamados') ) {
            return true;
        }
        if( $Chamado->isInternalCalled() ) {
            return $Chamado->getCliente()->equals($this);
        }
        return $Chamado->getFuncionario()->equals($this);
    }

    public function hasEnabledTools() {
        return !empty($this->ArFerramentas);
    }

    public function age() {
        $ItBirthTime = strtotime($this->ArDadosUsuario['DtNascimento']);
        $ItNowTime = strtotime(now());
        return floor( round( $ItNowTime - $ItBirthTime ) / YEAR );
    }

    public function isFavedCalled($Chamado) {
        if( empty($this->ArChamadosPreferidos) ) {return false;}
        foreach($this->ArChamadosPreferidos as $FavedCalled) {
            if( $FavedCalled->equals($Chamado) ) {
                return true;
            }
        }
        return false;
    }

    public function addCalledToFavourite($Chamado) {
        $this->ArChamadosPreferidos[] = $Chamado;
    }

    public function removeCalledFromFavourite($IDChamado) {
        foreach($this->ArChamadosPreferidos as $Key => $ChamadoPreferido) {
            if( $ChamadoPreferido->getIDChamado() == $IDChamado ) {
                unset($this->ArChamadosPreferidos[$Key]);
                return true;
            }
        }
        return false;
    }

    public function hasPreferredCalled() {
        return !empty($this->ArChamadosPreferidos);
    }

    //##Gets
    public function getIDUsuario() {
        return $this->IDUsuario;
    }

    public function getArDadosUsuario($StProp = false) {
        return!empty($StProp) ? $this->ArDadosUsuario[$StProp] : $this->ArDadosUsuario;
    }

    public function getArDadosAdministracao($StProp = false) {
        return!empty($StProp) ? $this->ArDadosAdministracao[$StProp] : $this->ArDadosAdministracao;
    }

    public function getDependentes($IDDependente = false) {
        return!empty($IDDependente) ? $this->ArDependentes[$IDDependente] : $this->ArDependentes;
    }

    public function getFerramentas($IDFeramenta = false) {
        return!empty($IDFeramenta) ? $this->ArFerramentas[$IDFeramenta] : $this->ArFerramentas;
    }

    public function getPreferencias($StProp = false) {
        return!empty($StProp) ? $this->ArPreferences[$StProp] : $this->ArPreferences;
    }

    public function getArAcao($StProp = false) {
        return!empty($StProp) ? $this->ArAcao[$StProp] : $this->ArAcao;
    }

    public function getTPerfil() {
        return $this->tPerfil;
    }

    public function getTDepartamento() {
        return $this->tDepartamento;
    }

    public function getReport($StProp) {
        return $this->Report[$StProp];
    }

    public function getArPagamentos() {
        return $this->ArPagamentos;
    }

    public function getArChamadosPreferidos() {
        return $this->ArChamadosPreferidos;
    }

    //##Sets
    public function setDadosUsuario($MxData, $StProp = false) {
        if (!empty($StProp)) {
            $this->ArDadosUsuario[$StProp] = $MxData;
        } else {
            $this->ArDadosUsuario = $MxData;
        }
    }

    public function setDadosAdministracao($MxData, $StProp = false) {
        if (!empty($StProp)) {
            $this->ArDadosAdministracao[$StProp] = $MxData;
        } else {
            $this->ArDadosAdministracao = $MxData;
        }
    }

    public function setDependente($Dependente) {
        $this->ArDependentes[$Dependente->getIDDependente()] = $Dependente;
    }

    public function setFerramenta($Ferramenta) {
        $this->ArFerramentas[$Ferramenta->getIDFerramenta()] = $Ferramenta;
    }

    public function setPreferencia($MxData, $StProp = false) {
        if (!empty($StProp)) {
            $this->ArPreferences[$StProp] = $MxData;
        } else {
            $this->ArPreferences = $MxData;
        }
    }

    public function setDepartamento($tDepartamento) {
        $this->tDepartamento = $tDepartamento;
    }

    public function setReport($Report) {
        $this->Report = $Report;
    }

    public function setTPerfil($tPerfil) {
        $this->tPerfil = $tPerfil;
    }

}

?>
